﻿#include <bits/stdc++.h>
#include "main.h"
#include "init.h"
#include "robot.h"
#include "boat.h"
#include "astar.h"
#include <pthread.h>
using namespace std;

int boat_capacity;   // 船的容积，最多能装的物品数（1~1000）
char ch_map[N][N];   // 字符地图，200x200
int frame_id;        // 当前帧序号
int money;           // 当前金钱数
Berth berth[berth_num]; // 泊位信息
vector<int> worth_berth; // 泊位优先级数组
unordered_map<Point, int, hash_fn> p_map; // 记录机器人的坐标
vector<Goods> goods_list; // 当前地图上的商品列表
int gds_map[n][n];	// 商品地图
int max_transport_time; // 场上泊位的最大运输时间
int min_transport_time = 2000; // 场上泊位的最小运输时间
int min_time_berthid; // 运货时间最短的泊位id
int maps = 0; // 记录地图，1为大图，2为迷宫图
unordered_set<Point, hash_fn> map1; // 1图泊位坐标
unordered_set<Point, hash_fn> map2; // 2图泊位坐标

int crack_times;
int missing_frame;
int goods_sum;
int goods_price_sum;
int get_goods_sum;
int get_goods_prices;

bool berth_cmp(int x, int y)
{
    return berth[x].worth < berth[y].worth;
}

// 初始化数据
void Init()
{
	//pthread_t tid;
	//pthread_create(&tid, NULL, init_berth_path, NULL);
	p_map.reserve(2e7);
	p_map.rehash(2e7); 
	map1.insert(Point(73, 73));
	map1.insert(Point(73, 121));
	map1.insert(Point(81, 59));
	map1.insert(Point(87, 13));
	map1.insert(Point(87, 35));
	map1.insert(Point(104, 194));
	map1.insert(Point(106, 25));
	map1.insert(Point(106, 70));
	map1.insert(Point(107, 105));
	map1.insert(Point(107, 171));

    map2.insert(Point(2, 174));
	map2.insert(Point(14, 175));
	map2.insert(Point(32, 175));
	map2.insert(Point(46, 175));
	map2.insert(Point(76, 175));
	map2.insert(Point(98, 175));
	map2.insert(Point(123, 175));
	map2.insert(Point(150, 42));
	map2.insert(Point(150, 57));
	map2.insert(Point(150, 109));

	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			gds_map[i][j] = -1;
		}
	}
	
    // 初始化地图信息，0~199
    for (int i = 0; i < n; i++)
        scanf("%s", ch_map[i]);

    // 初始化泊位信息，10行5列
    int flag_map1 = 1;
    int flag_map2 = 1;
    for (int i = 0; i < berth_num; i++)
    {
        int id;
        scanf("%d", &id);
        scanf("%d%d%d%d", &berth[id].p.x, &berth[id].p.y, &berth[id].transport_time, &berth[id].loading_speed);
        //fprintf(stderr, "%d %d\n", berth[id].transport_time, berth[id].loading_speed); 
    	//fflush(stdout);
        if (berth[id].transport_time > max_transport_time)
        	max_transport_time = berth[id].transport_time;
        if (berth[id].transport_time < min_transport_time) {
        	min_transport_time = berth[id].transport_time;
        	min_time_berthid = id;
        }
        if (map1.find(berth[id].p) == map1.end())
        	flag_map1 = 0;
        if (map2.find(berth[id].p) == map2.end())
        	flag_map2 = 0;
    }
    if (flag_map1)
    	maps = 1;
    else if (flag_map2)
    	maps = 2;
	// 初始化地图上所有点到泊位的路径长度
	init_berth_path();

    // 初始化船的容积，1~1000
    scanf("%d", &boat_capacity);
    
    // 初始化泊位优先级数组
    for (int i = 0; i < berth_num; i++) {
    	berth[i].worth = boat_capacity / berth[i].loading_speed + berth[i].transport_time;
    	worth_berth.push_back(i);
    }
    sort(worth_berth.begin(), worth_berth.end(), berth_cmp);
    
    //for (int i = 0; i < berth_num; i++) {
    //	fprintf(stderr, "%f\n", berth[worth_berth[i]].worth); 
    //	fflush(stdout);
    //}

    // 地图连通块上色
    init_connected();

    char okk[100];
    scanf("%s", okk);
    printf("OK\n");
    fflush(stdout);
}

// 每一帧的输入
void Input()
{
    // 获取新增货物
    int num; // 新增货物的数量（0~10）
    scanf("%d", &num);
    goods_sum += num;
    for (int i = 0; i < num; i++)
    {
        int x, y, price;
        scanf("%d%d%d", &x, &y, &price);
        // 初始化商品列表和商品地图
        goods_list.emplace_back(x, y, price, frame_id + 1000);
        gds_map[x][y] = goods_list.size() - 1;
        goods_price_sum += price;
    }

    // 获取机器人信息
    for (int i = 0; i < robot_num; i++)
    {
        scanf("%d%d%d%d", &robot[i].goods, &robot[i].p.x, &robot[i].p.y, &robot[i].status);
        // 统计每一帧没有任务的正常机器人
        if (robot[i].status == 1 && robot[i].move_target == 0) 
        	++no_task_rbt;
        
        // 把机器人当前坐标和下一帧移动的坐标加进去
        p_map[robot[i].p] = i;
        
	    // 假如未初始化可达泊位，则为其初始化
    	if (robot[i].reach_berth_status == 0) {
            robot[i].reach_berth_status = 1;
            for (int j = 0; j < berth_num; j++) {
                if (in_map[robot[i].p.x][robot[i].p.y] == in_map[berth[j].p.x][berth[j].p.y]) {
                    robot[i].reach_berth.push_back(j);
                }
            }
            sort(robot[i].reach_berth.begin(), robot[i].reach_berth.end(), berth_cmp);
            // 没有一个泊位可达
            if (robot[i].reach_berth.size() == 0)
                robot[i].reach_berth_status = 2;
        }
    }

	// 更新泊位的等待时间
	for (int i = 0; i < berth_num; i++) {
		++berth[i].wait_time;
	}

    // 获取船信息
    for (int i = 0; i < boat_num; i++) {
        scanf("%d%d\n", &boat[i].status, &boat[i].pos);
        //boat[i].capacity = boat_capacity;
    }

    char okk[100];
    scanf("%s", okk);
}


int main()
{
    /** 初始化 **/
    Init();
    
    int pre = 0;
    while (scanf("%d%d", &frame_id, &money) != EOF)
    {
        /** 获取当前帧数据 **/
        Input();
        missing_frame += frame_id - pre - 1;
        pre = frame_id;
        
        /** 处理一帧 **/
        // 操作机器人
		for (int i = 0; i < robot_num; i++) {
		    robot_task(i);
		}
		// 操作船
		for (int i = 0; i < boat_num; i++) {
		    boat_task(i);
		}
		
        /** 完成一帧的处理 **/
        astar_times = 0;
        no_task_rbt = 0;
        puts("OK");
        fflush(stdout);
    }
    //fprintf(stderr, "%d missing frame\n", missing_frame); // 打印丢帧数
    //fprintf(stderr, "%d crack times\n", crack_times); // 打印冲突数
    //fprintf(stderr, "goods num: %d\n", goods_sum); 
    //fprintf(stderr, "goods prices: %d\n", goods_price_sum); 
    //fprintf(stderr, "boat capacity: %d\n", boat_capacity); 
    //fprintf(stderr, "get goods num: %d\n", get_goods_sum); 
    //fprintf(stderr, "get goods prices: %d\n", get_goods_prices); 
    //fflush(stdout);

    return 0;
}
